package java8.stream;

import java8.Employee;
import java8.User;
import jdk.nashorn.internal.runtime.WithObject;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo1 {

    private static List<Employee> employees = new ArrayList<>();
    {
        employees.add(new Employee(1010,"刘强东",40,8000.12));
        employees.add(new Employee(1010,"刘强东",40,8000.34));
        employees.add(new Employee(1010,"刘强东",41,8000.99));
        employees.add(new Employee(1010,"刘强东",41,8000.21));
    }
    //1-筛选与切片
    @Test
    public void test1(){
        List<Employee> list = new ArrayList<>();
        //filter(Predicate p)——接收 Lambda ， 从流中排除某些元素。
        //练习：查询员工表中薪资大于7000的员工信息
        employees.stream().filter( (employee -> employee.getSalary() >= 7000 ) ).forEach(System.out::println);
        System.out.println();
        //limit(n)——截断流，使其元素不超过给定数量。
        employees.stream().limit(3).forEach(System.out::println);
        System.out.println();
        //skip(n) —— 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补
        employees.stream().skip(3).forEach(System.out::println);
        System.out.println();
        //distinct()——筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素

        employees.stream().distinct().forEach(System.out::println);
    }
    public static void main(String[] args) {
        List<User> list = new ArrayList<User>() {
            {
                add(new User(1l, "张三", 10, "清华大学"));
                add(new User(2l, "李四", 12, "清华大学"));
                add(new User(3l, "王五", 15, "清华大学"));
                add(new User(4l, "赵六", 12, "清华大学"));
                add(new User(5l, "田七", 25, "北京大学"));
                add(new User(6l, "小明", 16, "北京大学"));
                add(new User(7l, "小红", 14, "北京大学"));
                add(new User(8l, "小华", 14, "浙江大学"));
                add(new User(9l, "小丽", 17, "浙江大学"));
                add(new User(10l, "小何", 10, "浙江大学"));
            }
        };

        List<User> userList = list.stream().filter(user -> user.getSchool().equals("清华大学")).collect(Collectors.toList());
        User userone = list.stream().filter(u->u.getAge() > 18).findFirst().orElse(list.get(0));
        System.out.println("userone->"+userone.getName());

        userList.forEach(user -> System.out.println(user.getName()));

        System.out.println("所有user的年龄集合");
        List<Integer> userAgeList = list.stream().map(User::getAge).collect(Collectors.toList());
        System.out.println("userAgeList = " + userAgeList);

        List<List<User>> dList = new ArrayList<>();
        dList.add(list);

//        dList.stream().flatMap()



    }

    //映射
    @Test
    public void test2(){
        //map(Function f)——接收一个函数作为参数，将元素转换成其他形式或提取信息，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(String::toUpperCase).forEach(System.out::println);
        System.out.println();
        //练习1：获取员工姓名长度大于3的员工的姓名。
        employees.stream().map(Employee::getName).filter(name -> ((String) name).length() > 3).forEach(System.out::println);
        System.out.println();
        //练习2：
        Stream<Stream<Character>> streamStream = list.stream().map(Demo1::fromStringToStream);
        streamStream.forEach( (s) -> System.out.println(s.collect(Collectors.toList())));
        System.out.println();
        //flatMap(Function f)——接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
        Stream<Character> characterStream = list.stream().flatMap(Demo1::fromStringToStream);
        characterStream.forEach(System.out::println);
    }
    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> fromStringToStream(String str){//aa
        ArrayList<Character> list = new ArrayList<>();
        for(Character c : str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void floatMapTest(){
        String[] word = new String[] {"Hello","World"};
        List<String[]> collect = Arrays.stream(word).map(e -> e.split("")).collect(Collectors.toList());
        System.out.print(collect.get(0));

        List<String> collect1 = Arrays.stream(word).map(w -> w.split(""))
                .flatMap(Arrays::stream).collect(Collectors.toList());

        System.out.println(collect1);

        List<String> collect2 = Arrays.stream(word).collect(Collectors.toList());
        System.out.println("collect2"+collect2);

    }
    @Test
    public void floatMapTest2(){
        List<Integer> numbers1 = Arrays.asList(1, 2, 3);
        List<Integer> numbers2 = Arrays.asList(3, 4);
        List<int[]> pairs = numbers1.stream()
                .flatMap(i -> numbers2.stream()
                        .map(j -> new int[]{i, j})
                )
                .collect(Collectors.toList());

        List<String> collect = pairs.stream().map(e -> Arrays.toString(e)).collect(Collectors.toList());
        System.out.println(collect);

        numbers1.stream()
                .map(i -> numbers2.stream()
                        .map(j -> new int[]{i, j})
                )
                .collect(Collectors.toList());
    }
}
